home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / chat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-09  |  5.2 KB  |  264 lines

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <signal.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include "lutil.h"
  8. #include "xutil.h"
  9. #include "nodelist.h"
  10. #include "config.h"
  11.  
  12. int chat(node*,modem_string*,modem_string*,modem_string*,int,char*);
  13.  
  14. struct _strlist {
  15.     struct _strlist *next;
  16.     char *string;
  17. };
  18.  
  19. char *get_modem_string(modem_string*,node*);
  20. char *next_modem_string(node*);
  21. struct _strlist *sel_str(modem_string*,node*);
  22. void tidy_str(struct _strlist *);
  23.  
  24. void tidy_str(sl)
  25. struct _strlist *sl;
  26. {
  27.     struct _strlist *tmp;
  28.  
  29.     while (sl)
  30.     {
  31.         tmp=sl->next;
  32.         free(sl->string);
  33.         free(sl);
  34.         sl=tmp;
  35.     }
  36. }
  37.  
  38. struct _strlist *sel_str(msl,nlent)
  39. modem_string *msl;
  40. node *nlent;
  41. {
  42.     struct _strlist *sl=NULL,*tmp=NULL;
  43.     char *p,*q;
  44.  
  45.     for (p=get_modem_string(msl,nlent);p;p=next_modem_string(nlent))
  46.     {
  47.         if (sl == NULL)
  48.         {
  49.             sl=(struct _strlist *)
  50.                 xmalloc(sizeof(struct _strlist));
  51.             tmp=sl;
  52.         }
  53.         else
  54.         {
  55.             tmp->next=(struct _strlist *)
  56.                 xmalloc(sizeof(struct _strlist));
  57.             tmp=tmp->next;
  58.         }
  59.         tmp->next=NULL;
  60.         tmp->string=xmalloc(strlen(p)+1);
  61.         q=tmp->string;
  62.         while (*p)
  63.         {
  64.             if (*p == '\\') switch (*++p)
  65.             {
  66.             case '\0':    p--; break;
  67.             case '\\':    *q++='\\'; break;
  68.             case 'r':    *q++='\r'; break;
  69.             case 'n':    *q++='\n'; break;
  70.             case 't':    *q++='\t'; break;
  71.             case 's':    *q++=' '; break;
  72.             case ' ':    *q++=' '; break;
  73.             case 'b':    *q++='\b'; break;
  74.             }
  75.             else *q++ = *p;
  76.             p++;
  77.         }
  78.         *q='\0';
  79.     }
  80.     return sl;
  81. }
  82.  
  83. char *tranphone(char*,node*);
  84. char *tranphone(phone,nlent)
  85. char *phone;
  86. node *nlent;
  87. {
  88.     static char trp[32];
  89.     char buf[32];
  90.     char *tf,*p,*q;
  91.     int ln;
  92.  
  93.     if (phone == NULL) return NULL;
  94.     strncpy(trp,phone,sizeof(trp)-1);
  95.     for (tf=get_modem_string(phonetrans,nlent);tf;
  96.          tf=next_modem_string(nlent))
  97.     {
  98.         strncpy(buf,tf,sizeof(buf)-1);
  99.         if ((p=strchr(buf,'/'))) *p++='\0';
  100.         else p=buf+strlen(buf);
  101.         while (*p && isspace(*p)) p++;
  102.         q=buf+strlen(buf)-1;
  103.         while (*q && isspace(*q)) *q--='\0';
  104.         q=p+strlen(p)-1;
  105.         while (*q && isspace(*q)) *q--='\0';
  106.         ln=strlen(buf);
  107.         if (strncmp(phone,buf,ln) == 0)
  108.         {
  109.             strcpy(trp,p);
  110.             strncat(trp,phone+ln,sizeof(trp)-strlen(q)-1);
  111.             break;
  112.         }
  113.     }
  114.     return trp;
  115. }
  116.  
  117. int send_str(char *,char*,node*);
  118. int send_str(str,phone,nlent)
  119. char *str,*phone;
  120. node *nlent;
  121. {
  122.     char *p;
  123.  
  124.     p=str;
  125.     debug(18,"send_str \"%s\"",str);
  126.     while (*p)
  127.     {
  128.         if (*p == '\\') switch (*++p)
  129.         {
  130.         case '\0':    p--; break;
  131.         case '\\':    putchar('\\'); break;
  132.         case 'r':    putchar('\r'); break;
  133.         case 'n':    putchar('\n'); break;
  134.         case 't':    putchar('\t'); break;
  135.         case 'b':    putchar('\b'); break;
  136.         case 's':    putchar(' '); break;
  137.         case ' ':    putchar(' '); break;
  138.         case 'd':    sleep(1); break;
  139.         case 'p':    usleep(250000L); break;
  140.         case 'D':    if (phone) fputs(phone,stdout); break;
  141.         case 'T':    if (phone) fputs(tranphone(phone,nlent),stdout); break;
  142.         default:    putchar(*p); break;
  143.         }
  144.         else putchar(*p);
  145.         p++;
  146.     }
  147.     if (ferror(stdout))
  148.     {
  149.         logerr("$send_str error");
  150.         return 1;
  151.     }
  152.     else return 0;
  153. }
  154.  
  155. static int expired=0;
  156.  
  157. void almhdl(int);
  158. void almhdl(sig)
  159. int sig;
  160. {
  161.     expired=1;
  162.     debug(18,"timeout");
  163.     return;
  164. }
  165.  
  166. int expect_str(struct _strlist *,struct _strlist *,int);
  167. int expect_str(succs,errs,timeout)
  168. struct _strlist *succs,*errs;
  169. int timeout;
  170. {
  171.     int maxl,l,i,rc;
  172.     char *buf;
  173.     struct _strlist *ts;
  174.     int matched=0,smatch=0,ematch=0,ioerror=0;
  175.  
  176.     maxl=0;
  177.     for (ts=errs;ts;ts=ts->next) 
  178.         if ((l=strlen(ts->string)) > maxl)
  179.             maxl=l;
  180.     for (ts=succs;ts;ts=ts->next) 
  181.         if ((l=strlen(ts->string)) > maxl)
  182.             maxl=l;
  183.     buf=xmalloc(maxl+1);
  184.     memset(buf,0,maxl+1);
  185.  
  186.     expired=0;
  187.     signal(SIGALRM,almhdl);
  188.     alarm(timeout);
  189.     while (!matched && !expired && !ioerror && !feof(stdin))
  190.     {
  191.         for (i=0;i<maxl;i++) buf[i]=buf[i+1];
  192.         if ((rc=read(0,&(buf[maxl-1]),1)) != 1)
  193.         {
  194.             logerr("$chat got read return %d",rc);
  195.             ioerror=1;
  196.         }
  197.         if (expired) debug(18,"chat got TIMEOUT");
  198.         else debug(18,"chat got '%s'",
  199.             printablec(buf[maxl-1]));
  200.         for (ts=errs;ts && !matched;ts=ts->next)
  201.         if (strcmp(ts->string,buf+maxl-strlen(ts->string)) == 0)
  202.         {
  203.             matched=1;
  204.             ematch=1;
  205.             loginf("chat got \"%s\", aborting",ts->string);
  206.         }
  207.         for (ts=succs;ts && !matched;ts=ts->next)
  208.         if (strcmp(ts->string,buf+maxl-strlen(ts->string)) == 0)
  209.         {
  210.             matched=1;
  211.             smatch=1;
  212.             loginf("chat got \"%s\", continue",ts->string);
  213.         }
  214.         if (expired) loginf("chat got timeout, aborting");
  215.         else
  216.         if (ferror(stdin)) loginf("chat got error, aborting");
  217.         if (feof(stdin)) logerr("chat got EOF, aborting");
  218.     }
  219.     alarm(0);
  220.     signal(SIGALRM,SIG_DFL);
  221.  
  222.     rc=!(matched && smatch);
  223.     free(buf);
  224.     return rc;
  225. }
  226.  
  227. int chat(nlent,send,success,error,timeout,phone)
  228. node *nlent;
  229. modem_string *send;
  230. modem_string *success;
  231. modem_string *error;
  232. int timeout;
  233. char *phone;
  234. {
  235.     char *sends;
  236.     struct _strlist *succs=NULL, *errs=NULL;
  237.     int rc;
  238.  
  239.     if ((sends=get_modem_string(send,nlent)) == NULL)
  240.     {
  241.         logerr("chat cannot find appropriate send string");
  242.         return 1;
  243.     }
  244.     if ((success) && ((succs=sel_str(success,nlent)) == NULL))
  245.     {
  246.         logerr("chat cannot find appropriate expect string");
  247.         return 1;
  248.     }
  249.     if ((error) && ((errs=sel_str(error,nlent)) == NULL))
  250.     {
  251.         tidy_str(succs);
  252.         logerr("chat cannot find appropriate error string");
  253.         return 1;
  254.     }
  255.  
  256.     rc=send_str(sends,phone,nlent);
  257.     if ((rc == 0) && (errs) && (succs)) 
  258.         rc=expect_str(succs,errs,timeout);
  259.  
  260.     tidy_str(succs);
  261.     tidy_str(errs);
  262.     return rc;
  263. }
  264.